home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / radar.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  21KB  |  850 lines

  1. /* --------------------------------- radar.c -------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* paint the radar info onto the Head Up Display.
  8. */
  9.  
  10. #include "plane.h"
  11.  
  12.  
  13. LOCAL_FUNC void NEAR show_all_intel (VIEW *view, OBJECT *pov, OBJECT *p, int sx,
  14.     int sy, int bspeed, int orgx, int orgy, int maxx, int maxy, int ss,
  15.     int mode, int shifty);
  16. LOCAL_FUNC void NEAR show_intel (VIEW *view, OBJECT *pov, OBJECT *p,
  17.     OBJECT *target, int sx, int sy, int orgx, int orgy, int maxx, int maxy,
  18.     int ss, int mode, int shifty);
  19. LOCAL_FUNC void NEAR show_box (OBJECT *p, OBJECT *target, int x, int y, int dx,
  20.     int dy, int mode, int off_screen, int dist, int tti,
  21.     int closure, int bottom, int right, int hbottom, int hleft, int ss,
  22.     int shifty);
  23. LOCAL_FUNC void NEAR show_range (OBJECT *p, int dist, int closure, int orgx,
  24.     int orgy, int sx, int sy, int tx, int ss, int VVD[2]);
  25. LOCAL_FUNC void NEAR check_shoot (OBJECT *p, int orgx, int orgy, int sx, int sy,
  26.     int dx, int dy, int ty, int ss);
  27. LOCAL_FUNC int  NEAR show_select (VIEW *view, OBJECT *p, int radar, int orgx,
  28.     int orgy, int sx, int sy, int maxx, int shifty);
  29. LOCAL_FUNC void NEAR show_bombs (VIEW *view, OBJECT *p, OBJECT *pov, int orgx,
  30.     int orgy, int sx, int sy, int maxx, int maxy, int clipx, int clipy,
  31.     int shifty, int ss);
  32. LOCAL_FUNC void NEAR show_target (OBJECT *p, OBJECT *target, VECT RR, int dist,
  33.     int closure, int tti, int orgx, int orgy, int maxx, int maxy, int ss);
  34.  
  35. extern ANGLE FAR
  36. screen_direction (VIEW *view, VECT RR)
  37. {
  38.     int    s, x, y, z;
  39.  
  40.     s = VP->z;                /* get maximum */
  41.     if (s < VP->maxx)
  42.         s = VP->maxx;
  43.     if (s < VP->maxy)
  44.         s = VP->maxy;
  45.     x = muldiv (RR[X], VP->maxx, s);
  46.     y = muldiv (RR[Z], VP->maxy, s);
  47.     z = muldiv (RR[Y], VP->z, s);
  48.  
  49.     s = ihypot2d (x, y);
  50.     return (ATAN (s, z));
  51. }
  52.  
  53. extern void FAR
  54. show_radar (HUD *h, VIEW *view, OBJECT *p, OBJECT *pov, int orgx, int orgy,
  55.     int maxx, int maxy, int tx, int ty, int ss, int clipx, int clipy,
  56.     int sx, int sy, int shifty, int VVD[2], int mode, int hon)
  57. {
  58.     int    dx, dy, ds, x, y, closure, have_reticule, f16, f156cl, fa18;
  59.     int    i, dist, off_screen, toff, bspeed, rv, dt, dti, tti, tbox;
  60.     int    tdir, bx, by, radar, selecting, dmode;
  61.     Ushort    savehud;
  62.     OBJECT    *target;
  63.     VECT    RRT, RR, V;
  64.     LVECT    LL, IP;
  65.     int    D[2], DD[2];
  66.     long    ldist;
  67.  
  68.     if (h->flags & HF_ETHER) {
  69.         clipx = maxx;
  70.         clipy = maxy;
  71.         shifty = 0;
  72.     }
  73.  
  74. /* bomb impact points
  75. */
  76.     if (WE_MK82 == EX->weapon)
  77.         show_bombs (view, p, pov, orgx, orgy, sx, sy, maxx, maxy, clipx,
  78.             clipy, shifty, ss);
  79.  
  80.     show_compass (h, p, mode);
  81.  
  82.     radar = EX->radar;
  83.     if (!(radar & R_ON))
  84.         return;
  85.  
  86.     i = EX->hud1 & HUD_TYPES;
  87.     f16 = i == HUD_F16;
  88.     f156cl = f16 || i == HUD_F15 || i == HUD_CLASSIC;
  89.     fa18 = i == HUD_FA18;
  90.     have_reticule = 0;
  91.     dx = ds = toff = 0;    /* avoid compiler warning */
  92.  
  93.     if (WE_MK82 == EX->weapon)
  94.         bspeed = BombSpeed (p, V)/VONE;
  95.     else
  96.         bspeed = BulletSpeed (p, V)/VONE;
  97.  
  98.     if ((radar & R_INTEL) ||
  99.         (mode == HDT_MAP || mode == HDT_RADAR)) {
  100.         show_all_intel (view, pov, p, sx, sy, bspeed, orgx, orgy,
  101.             maxx, maxy, ss, mode, (mode == HDT_HUD) ? shifty: 0);
  102.         return;
  103.     }
  104. /* Check if we have a target at all.
  105. */
  106.     if (F(target = EX->target) || target->id != EX->tid) {
  107.         target = 0;
  108.         EX->target = 0;
  109.     }
  110. /* if selecting, show selection circle and best target (if we have one).
  111. */
  112.     selecting = EX->weapon
  113.             && (radar & (R_SELECT3|R_SELECT20|R_SELECT5))
  114.             && !(target && (radar & R_LOCK));
  115.  
  116.     if (selecting && hon)
  117.         dy = show_select (view, p, radar, orgx, orgy, sx, sy, maxx,
  118.                 shifty);
  119.     else
  120.         dy = 0;            /* avoid compiler warning */
  121.  
  122.     if (!target)
  123.         return;
  124.  
  125. /* get target position, distance, closure and time to intercept.
  126. */
  127.     Vsub (LL, p->R, target->R);
  128.     ldist = lhypot3d (LL);
  129.     dti = dist = (int)(ldist/VONE);
  130.     if (WE_MK82 == EX->weapon) {
  131.         closure = (int)((p->R[Z]-target->R[Z])/VONE);
  132.         dt = BombIP (p->R, V, target->R[Z], IP);
  133.         tti = (dt < 6000) ? dt/10 : 600;
  134.     } else {
  135.         if (dist)
  136.             closure = (int)(-(LL[X]*(p->V[X] - EX->tspeed[X]) +
  137.                       LL[Y]*(p->V[Y] - EX->tspeed[Y]) +
  138.                       LL[Z]*(p->V[Z] - EX->tspeed[Z])
  139.                      ) / (ldist*VONE));
  140.         else
  141.             closure = 0;
  142.         tti = (dist/60 < closure) ? muldiv (dist, 10, closure) : 600;
  143.     }
  144.  
  145.     objects_show (1, view, pov, 0, target->R, RRT);
  146.     tdir = screen_direction (view, RRT);
  147.  
  148.     tbox = fa18 ? F18TBOX : (f16 ? F16TBOX : F15TBOX);
  149.     bx = fmul (sx, tbox);
  150.     by = fmul (sy, tbox);
  151.     if (selecting) {
  152.         if (hon)
  153.             show_data (p, orgx-3*ss, orgy+dy+ss, 1,
  154.                 EX->hud1 & HUD_KNOTS, dist, closure,
  155.                 get_name (p, target, 0), tti, 0, ss, ST_HFG);
  156.         off_screen = clip_to_screen (D, RRT, maxx, maxy,
  157.                 clipx-bx, clipy-by, shifty);
  158.         show_brect (orgx+D[X], orgy-D[Y], bx, by, FCON(.5), ST_HFG,
  159.             off_screen);
  160.         return;
  161.     }
  162. /* target highlighting box
  163. */
  164.     if (mode == HDT_TARGET || mode == HDT_PAN) {
  165.         show_target (p, target, RRT, dist, closure, tti, orgx, orgy,
  166.                 maxx, maxy, ss);
  167.         return;
  168.     }
  169.  
  170.     off_screen = clip_to_screen (D, RRT, maxx, maxy, clipx-bx, clipy-by,
  171.             shifty);
  172.  
  173.     if (HDT_HUD != mode && !(HDT_FRONT == mode && EX->hud & HUD_RETICLE))
  174.         goto no_reticule;
  175.  
  176.     rv = fa18 ? F18RAIM : (f16 ? F16RAIM : F15RAIM);
  177.     dx = fmul (sx, rv);
  178.     dy = fmul (sy, rv);
  179.     ds = 3;
  180.  
  181. /* bomb aiming reticule
  182. */
  183.     if (WE_MK82 == EX->weapon) {
  184.         objects_show (1, view, pov, 0, IP, RR);
  185.  
  186.         toff = clip_to_screen (DD, RR, maxx, maxy, clipx-dx, clipy-dy,
  187.                     shifty);
  188.         gr_color (ST_HFG);
  189.         gr_move (orgx+VVD[X], orgy-VVD[Y]);
  190.         gr_draw (orgx+DD[X],  orgy-DD[Y]);
  191.  
  192.         have_reticule = 1;
  193.         goto no_reticule;
  194.     }
  195. /* target-speed corrected gun aiming reticule
  196. */
  197.     dt = rv = 0;
  198.  
  199.     if (dist/4 > bspeed)
  200.         goto no_reticule;
  201.     have_reticule = 1;
  202.     SetKillCorrection (p, target, RR, &dt);
  203.  
  204.     if (EX->hud & HUD_ROSS) {
  205.  
  206. /* Ross style aiming reticule
  207. */
  208.         LVcopy (LL, target->R);
  209.         Vinc (LL, RR);
  210.         objects_show (1, view, p, 0, LL, RR);
  211.  
  212.         toff = clip_to_screen (DD, RR, maxx, maxy,
  213.             clipx-2*tx, clipy-2*ty, shifty);
  214.         show_brect (orgx+DD[X], orgy-DD[Y], tx*2, ty*2, FCON(.5),
  215.             ST_HFGI, toff);
  216.         DD[X] = DD[Y] = 0;    /* reticule at center */
  217.         toff = 0;
  218.  
  219.     } else {
  220.  
  221. /* Eyal style aiming reticule
  222. */
  223.         Vsub (LL, p->R, RR);
  224.         LL[X] += muldiv (V[X], dt, VONE*1000) * (long)VONE;
  225.         LL[Y] += muldiv (V[Y], dt, VONE*1000) * (long)VONE;
  226.         LL[Z] += muldiv (V[Z], dt, VONE*1000) * (long)VONE;
  227.  
  228.         objects_show (1, view, p, 0, LL, RR);
  229.         toff = clip_to_screen (DD, RR, maxx, maxy, clipx-dx, clipy-dy,
  230.                     shifty);
  231.     }
  232.     tti = dt/100;
  233. no_reticule:
  234.  
  235.     if (EX->hud1 & HUD_CORNER) {
  236.         dmode = 2;
  237.         x = orgx-sx+2;
  238.         y = orgy+sy-2;
  239.         if (EX->hud & HUD_BIG) {
  240.             x += 6*tx;
  241.             if (!(EX->hud1 & HUD_TOP))
  242.                 y -= 6*ty + ss;
  243.         } else {
  244.             if (!(EX->hud1 & HUD_TOP))
  245.                 y -= ss;
  246.         }
  247.     } else {
  248.         dmode = 0;
  249.         x = y = 0;
  250.     }
  251.  
  252. /* Show the aiming reticule.
  253. */
  254.     savehud = EX->hud;
  255.     if (have_reticule) {
  256.         show_piper (h, p, target, orgx+DD[X], orgy-DD[Y],
  257.             dx, dy, ds, dmode, toff, dti, tti, closure,
  258.             orgx, orgy, clipx, clipy, y, x, ss, shifty);
  259.         check_shoot (p, orgx, orgy, sx, sy, DD[X], DD[Y], dy,
  260.             ss);
  261.         EX->hud &= ~HUD_DATA;    /* don't show data again */
  262.     }
  263.  
  264. /* Show the target designator and target pointer.
  265. */
  266.     if (EX->hud & HUD_TARGET) {
  267.         if ((mode == HDT_FRONT || mode == HDT_HUD) &&
  268.             !((EX->hud2 & HUD_HIDETGT) && have_reticule &&
  269.               iabs (D[X]-DD[X]) < (Uint)2*bx &&
  270.               iabs (D[Y]-DD[Y]) < (Uint)2*by)) {
  271.             if (off_screen && (EX->hud2 & HUD_TPOINTER)) {
  272.                 tdir = ANG2DEG(tdir);
  273.                 if (EX->hud2 & HUD_VPOINTER) {
  274.                     if ((i = tdir) > 90)
  275.                         i = 90;
  276.                     dx = muldiv (D[X], i, 90);
  277.                     dy = muldiv (D[Y], i, 90);
  278.                 } else {
  279.                     i = ihypot2d (D[X], D[Y]);
  280.                     dx = h->sy - h->shifty;
  281.                     i = muldiv (i, h->sy, dx);
  282.                     i *= 2;
  283.                     dx = muldiv (sx, D[X], i);
  284.                     dy = muldiv (sy, D[Y], i);
  285.                 }
  286.                 gr_color (h->fg);
  287.                 gr_move (orgx,    orgy);
  288.                 gr_draw (orgx+dx, orgy-dy);
  289.                 i = (tdir >= 100) ? 3 : 2;
  290.                 stroke_frac (h->orgx - 3*h->tx - i*h->dd - 2,
  291.                     h->orgy + h->ss/2, (long)tdir,
  292.                     i, 0, h->ss, h->fg);
  293.             }
  294.             if (off_screen && (h->flags & HF_ETHERFRAME)) {
  295.                 clip_to_ether (h, D, clipx-bx, clipy-by);
  296.                 show_rect (orgx+D[X], orgy-D[Y], h->ethertx,
  297.                     h->etherty, h->fg, 0);
  298.             } else
  299.                 show_box (p, target, orgx+D[X], orgy-D[Y],
  300.                     bx, by, dmode, off_screen, dti, tti,
  301.                     closure, orgy+clipy, orgx+clipx, y, x,
  302.                     ss, shifty);
  303.               }
  304.     }
  305.     if (f156cl && hon &&
  306.         (have_reticule || (target && (EX->hud & HUD_TARGET))))
  307.         show_range (p, dti, closure, orgx, orgy, sx, sy, tx, ss, VVD);
  308.     EX->hud = savehud;
  309. }
  310.  
  311. LOCAL_FUNC void NEAR
  312. show_all_intel (VIEW *view, OBJECT *pov, OBJECT *p, int sx, int sy,
  313.     int bspeed, int orgx, int orgy, int maxx, int maxy, int ss, int mode,
  314.     int shifty)
  315. {
  316.     OBJECT    *target;
  317.  
  318.     for (target = CO; target; target = target->next) {
  319.         if (!(target->shflags & SH_BEHIT))
  320.             continue;
  321.         if ((EX->radar&R_INTELCC) && !(target->flags&F_CC))
  322.             continue;
  323.         if (!(st.flags1&SF_EXTVIEW) && target == p)
  324.             continue;
  325.         show_intel (view, pov, p, target, sx, sy, orgx, orgy,
  326.             maxx, maxy, ss, mode, shifty);
  327.     }
  328. }
  329.  
  330. LOCAL_FUNC void NEAR
  331. show_intel (VIEW *view, OBJECT *pov, OBJECT *p, OBJECT *target, int sx,
  332.     int sy, int orgx, int orgy, int maxx, int maxy, int ss, int map,
  333.     int shifty)
  334. {
  335.     VECT    RR;
  336.     int    D[2], off_screen, size, dx, dy, tti, speed, c, s, t;
  337.     long    dist;
  338.  
  339.     if (map == HDT_MAP)
  340.         map = 1;
  341.     else if (map == HDT_RADAR)
  342.         map = 2;
  343.     else
  344.         map = 0;
  345.  
  346.     if (map) {
  347.         if (CC == target)
  348.             dist = CC->R[Z]/VONE;
  349.         else
  350.             dist = (target->R[Z] - CC->R[Z])/VONE;
  351.         tti = 0;
  352.     } else {
  353.         dist = ldist3d (p->R, target->R)/VONE;
  354. #if 0
  355.         Vcopy (V, p->V);
  356.         Vdec (V, EX->tspeed);
  357.         speed = est_hyp (V[X], V[Y], V[Z])/VONE; /* closure speed */
  358. #else
  359.         speed = iabs(p->speed/VONE);        /* linear speed */
  360. #endif
  361.         if (dist/100 >= speed)
  362.             tti = 999;
  363.         else if (dist > VONE)
  364.             tti = (int)(dist*10/speed);
  365.         else
  366.             tti = muldiv ((int)dist, 10, speed);
  367.         if (dist > 31999)
  368.             dist = 31999;
  369.     }
  370.  
  371.     objects_show (1, view, pov, 0, target->R, RR);
  372.  
  373.     if (map || tti == 999) {
  374.         dx = fmul (sx, MAPBOX/4);
  375.         dy = fmul (sy, MAPBOX/4);
  376.     } else {
  377.         size = muldiv (MAPBOX, 6*600-4*tti, 6*600);
  378.         dx = fmul (sx, size);
  379.         dy = fmul (sy, size);
  380.     }
  381.     
  382.     off_screen = clip_to_screen (D, RR, maxx, maxy, maxx-dx, maxy-dy,
  383.                     shifty);
  384. #if 1
  385.     if (off_screen)
  386.         return;
  387. #endif
  388.     D[X] = orgx + D[X];
  389.     D[Y] = orgy - D[Y];
  390.     show_box (p, target, D[X], D[Y], dx, dy, 1, off_screen,
  391.         (int)dist, tti, 0, orgy+maxy+shifty, orgx+maxx, 0, 0, ss, 0);
  392.  
  393. /* show target horizontal speed vector.
  394. */
  395.     if (map) {
  396.         t = 25*VONE;        /* one boxfull for 100 knots */
  397.         dx = muldiv (target->V[X], dx, t);
  398.         dy = muldiv (target->V[Y], dy, t);
  399.         if (dx || dy) {
  400.             if (2 == map) {
  401.                 s = -pov->sinz;
  402.                 c =  pov->cosz;
  403.                 t  = fmul (dx, c) - fmul (dy, s);
  404.                 dy = fmul (dx, s) + fmul (dy, c);
  405.                 dx = t;
  406.             }
  407.             gr_color (ST_HFGI);
  408.             add_segment (D[X], D[Y], D[X]+dx, D[Y]-dy,
  409.                 orgx, orgy, maxx, maxy, 0);
  410.         }
  411.     }
  412. }
  413.  
  414. extern void FAR
  415. show_data (OBJECT *p, int datax, int datay, int detail, int knots, int dist,
  416.     int closure, char *name, int tti, int mode, int ss, Uint color)
  417. {
  418.     long    tt;
  419.  
  420.     if (detail) {
  421.         if (knots)
  422.             tt = 3L*dist + fmul (dist, 4601);    /* feet */
  423.         else
  424.             tt = dist;
  425.         if (tt >= 10000L || tt <= -10000L)
  426.             stroke_frac (datax, datay, tt/100, 0, 1, ss, color);
  427.         else
  428.             stroke_frac (datax, datay, tt/10, 3, 2, ss, color);
  429.         datay += ss;
  430.  
  431.         if (!(1&mode)) {
  432.             tt = closure;
  433.             if (knots) {
  434.                 if (WE_M61 == EX->weapon)    /* knots */
  435.                     tt += fmul (closure, 15465);
  436.                 else                /* feet */
  437.                     tt = 3*tt + fmul (closure, 4601);
  438.             }
  439.             stroke_num (datax, datay, tt, ss, color);
  440.             datay += ss;
  441.             stroke_frac (datax, datay, (long)tti, 0, 1, ss, color);
  442.             datay += ss;
  443.         }
  444.  
  445.     }
  446.     if (name)
  447.         stroke_str (datax, datay, name, ss, color);
  448. }
  449.  
  450. extern char * FAR
  451. get_name (OBJECT *p, OBJECT *target, int mode)
  452. {
  453.     char        *name;
  454.     static char    title[40];
  455.  
  456.     if (target->flags & F_CC) {
  457.         if (target->flags & F_IMPORTED) {
  458.             if (target->flags & F_FRIEND)
  459.                 name = target->rplayer->name;
  460.             else {
  461.                 strcpy (title, target->rplayer->name);
  462.                 strcat (title, ":");
  463.                 strcat (title, target->rplayer->team);
  464.                 name = title;
  465.             }
  466.         } else
  467.             name = st.nikname;
  468.     } else if (mode != 1 || (EX->hud1 & HUD_INAME)) {
  469.         title[0] = '*';
  470.         if (IS_PLANE(target))
  471.             strcpy (title+1, EEP(target)->name);
  472.         else                    /* object type */
  473.             strcpy (title+1, TITLE(target));
  474.         name = title;
  475.     } else
  476.         name = 0;
  477.     return (name);
  478. }
  479.  
  480. LOCAL_FUNC void NEAR
  481. show_box (OBJECT *p, OBJECT *target, int x, int y, int dx, int dy, int mode,
  482.     int off_screen, int dist, int tti, int closure, int bottom, int right,
  483.     int hbottom, int hleft, int ss, int shifty)
  484. {
  485.     int    t, datax, datay, nlines, knots;
  486.     char    *name;
  487.     Uint    color;
  488.  
  489.     color = (1 == mode && (target->flags&F_CC))
  490.         ? (target->flags&F_FRIEND ? ST_FRIEND : ST_FOE)
  491.         : ST_HFG;
  492.  
  493.     knots = EX->hud1 & HUD_KNOTS;
  494.     if (NEWTGT(p))
  495.         t = NEWTGT(p)--&1;
  496.     else
  497.         t = 1;
  498.  
  499.     if (t) {
  500.         if (EX->target == target && (EX->radar&R_LOCK))
  501.             show_rect (x, y, dx, dy, color, 0);
  502.         else
  503.             show_brect (x, y, dx, dy, FCON(.5), color, 0);
  504.         if (off_screen == 1)            /* ahead */
  505.             show_plus (x, y, dx, dy, color);
  506.         else if (off_screen == 2)        /* behind */
  507.             show_x (x, y, dx, dy, color);
  508.     }
  509.  
  510.     if (EX->hud & HUD_DATA) {
  511.         name = get_name (p, target, mode);
  512.         nlines = ((1&mode) ? 1 : 3) + !!name;
  513.  
  514.         if (2&mode) {
  515.             datax = hleft;
  516.             datay = hbottom+shifty-(nlines-1)*ss;
  517.         } else {
  518.             if (y+dy+nlines*ss >= bottom+shifty)
  519.                 datay = y-dy-2-(nlines-1)*ss;
  520.             else
  521.                 datay = y+dy+ss;
  522.             datax = num_size (9L, ss) * (dist<0 ? 5 : 4);
  523.             if (name) {
  524.                 t = stroke_size (name, ss);
  525.                 if (t < datax)
  526.                     t = datax;
  527.             } else
  528.                 t = datax;
  529.  
  530.             t = right-t;
  531.             datax = x-dx;
  532.             if (datax > t)
  533.                 datax = t;
  534.         }
  535.  
  536.         show_data (p, datax, datay, 1, knots, dist, closure, name,
  537.                 tti, mode, ss, color);
  538.     }
  539. }
  540.  
  541. extern int FAR
  542. get_center (OBJECT *p, int orgy, int sy, int VVD[2])
  543. {
  544.     int    y, y0, hudtype;
  545.  
  546.     hudtype = EX->hud1 & HUD_TYPES;
  547.     if (HUD_F16 == hudtype) {
  548.         if (EX->equip & EQ_GEAR) {
  549.             y0 = fmul (sy, F16CNTRG);
  550.             y = -VVD[Y] - fmul (sy, F16HEADTOP);
  551.             if (y0 < y)
  552.                 y0 = y;
  553.         } else
  554.             y0 = fmul (sy, F16CNTR);
  555.     } else if (HUD_F15 == hudtype)
  556.         y0 = fmul (sy, F15CNTR);
  557.     else
  558.         y0 = 0;
  559.     y0 += orgy;
  560.     return (y0);
  561. }
  562.  
  563. /* radar range scale
  564. */
  565.  
  566. LOCAL_FUNC void NEAR
  567. show_range (OBJECT *p, int dist, int closure, int orgx, int orgy, int sx,
  568.     int sy, int tx, int ss, int VVD[2])
  569. {
  570.     int    i, x, y, y0, t, dm, range, ss2, hud1, hudtype;
  571.  
  572.     hud1 = EX->hud1;
  573.     hudtype = hud1 & HUD_TYPES;
  574.  
  575.     ss2 = ss/2;
  576.     if (hud1 & HUD_KNOTS) {
  577.         dist = fmul (dist, FCON(0.54));        /* nm/1000 */
  578.         if (WE_M61 == EX->weapon)        /* knots */
  579.             closure = fmul (closure, FCON(1.943));
  580.         else                    /* feet/sec */
  581.             closure = fmul (closure, FCON(3.28/4))*4;
  582.     }
  583.     gr_color (ST_HFG);
  584.     if (hudtype == HUD_F15 || hudtype == HUD_F16 ||
  585.         hudtype == HUD_CLASSIC) {
  586.         if (dist > 10000)            /* full scale range */
  587.             range = 20000;
  588.         else
  589.             range = 10000;
  590.  
  591.         y0 = get_center (p, orgy, sy, VVD);
  592.         if (HUD_F16 == hudtype) {
  593.             dm = num_size (9L, ss);
  594.             x = orgx + fmul (sx, F16ALT) - 3*dm;
  595.             y = muldiv (sy, 8, 40/2);
  596.             y0 += y/2 - 2*ss;
  597.         } else if (HUD_F15 == hudtype) {
  598.             x = orgx + fmul (sx, F15RDR);
  599.             y = fmul (sy, F15RDRS);        /* scale size */
  600.             y0 += muldiv (sy, 8, 15);
  601.         } else {
  602.             x = orgx + sx-2*ss-2*tx;
  603.             y = muldiv (sy, 10, 15);
  604.             y0 += muldiv (sy, 8, 15);
  605.         }
  606.  
  607.         gr_move (x, y0);
  608.         gr_draw (x, y0-y);
  609.             t = range/1000;                /* radar range */
  610.         stroke_num (x+tx+2, y0-y/2+ss2, (long)t/2, ss, ST_HFG);
  611.         stroke_num (x-ss2,  y0-y-1,     (long)t,   ss, ST_HFG);
  612.         for (i = 0; i < 5; ++i) {
  613.             t = y0 - muldiv (i, y, 5-1);
  614.             gr_move (x,    t);
  615.             gr_draw (x+tx, t);
  616.         }
  617.  
  618.         y = y0 - muldiv (y, dist, range);
  619.     } else {
  620.         x = orgx + fmul (sx, F15ALT);
  621.         y = orgy + muldiv (sy, 8, 15);
  622.     }
  623.     gr_move (x-ss2, y-ss2);
  624.     gr_draw (x,     y);
  625.     gr_draw (x-ss2, y+ss2);
  626.  
  627.     closure = closure/10*10;
  628.     dm = num_size ((long)closure, ss);
  629.     stroke_num (x-dm-ss2, y+ss2, (long)closure, ss, ST_HFG);
  630. }
  631.  
  632. LOCAL_FUNC void NEAR
  633. check_shoot (OBJECT *p, int orgx, int orgy, int sx, int sy, int dx, int dy,
  634.     int ty, int ss)
  635. {
  636.     int    t, x, y;
  637.  
  638.     if ((EX->radar&R_SHOOT)) {
  639.         t = stroke_size ("SHOOT", ss)/2;
  640.         x = orgx+dx;
  641.         if (x-t < orgx-sx)
  642.             x = orgx-sx;
  643.         else if (x+t > orgx+sx)
  644.             x = orgx+sx-t;
  645.         else
  646.             x -= t;
  647.         t = ss;
  648.         y = orgy-dy-ty;
  649.         if (y-t < orgy-sy)
  650.             y = orgy-sy+t;
  651.         stroke_str (x, y, "SHOOT", ss, ST_HFGI);
  652.     }
  653. }
  654.  
  655. #if 0        /* keep this one for old times sake... */
  656. LOCAL_FUNC void NEAR show_reticule (OBJECT *p, int x, int y, int tx, int ty,
  657.     int orgx, int orgy, int sx, int sy, int off_screen, int c, int ss);
  658.  
  659. LOCAL_FUNC void NEAR
  660. show_reticule (OBJECT *p, int x, int y, int tx, int ty, int orgx, int orgy,
  661.     int sx, int sy, int off_screen, int c, int ss)
  662. {
  663.     int    dx, dy;
  664.  
  665.     check_shoot (p, orgx, orgy, sx, sy, x, y, ty, ss);
  666.  
  667.     x = orgx + x;
  668.     y = orgy - y;
  669.  
  670.     dx = tx/2;
  671.     dy = ty/2;
  672.  
  673.     gr_color (c);
  674.     gr_move (x+tx,   y+dy-1);
  675.     gr_draw (x+tx,   y+dy);
  676.     gr_move (x+dx-1, y+ty);
  677.     gr_draw (x+dx,   y+ty);
  678.     gr_move (x-dx+1, y+ty);
  679.     gr_draw (x-dx,   y+ty);
  680.     gr_move (x-tx,   y+dy-1);
  681.     gr_draw (x-tx,   y+dy);
  682.     gr_move (x-tx,   y-dy+1);
  683.     gr_draw (x-tx,   y-dy);
  684.     gr_move (x-dx+1, y-ty);
  685.     gr_draw (x-dx,   y-ty);
  686.     gr_move (x+dx-1, y-ty);
  687.     gr_draw (x+dx,   y-ty);
  688.     gr_move (x+tx,   y-dy+1);
  689.     gr_draw (x+tx,   y-dy);
  690.     if (off_screen)
  691.         show_x (x, y, tx, ty, c);
  692. }
  693. #endif
  694.  
  695. #define SEL3D    (D90/54)        /* 3.3 degrees wide circle */
  696.  
  697. LOCAL_FUNC int NEAR
  698. show_select (VIEW *view, OBJECT *p, int radar, int orgx, int orgy, int sx,
  699.     int sy, int maxx, int shifty)
  700. {
  701.     int    i, rx, ry, dx, dy, ox, oy;
  702.     ANGLE    a;
  703.  
  704.     gr_color (ST_HFG);
  705.     if (radar & R_SELECT3) {
  706.         i = muldiv (VP->maxx, sx, maxx);
  707.         a = ATAN (i, VP->z);
  708.         if (a < SEL3D)
  709.             i = FONE;
  710.         else
  711.             i = muldiv (FONE, SEL3D, a);
  712.  
  713.         dx = fmul (sx, i);
  714.         dy = fmul (sy, i);
  715.  
  716.         gr_ellipse (orgx, orgy, dx, dy);
  717.     } else if (radar & R_SELECT20) {
  718.         orgy += shifty;
  719.         rx = fmul (sx, RSELECT20);
  720.         ry = fmul (sy, RSELECT20);
  721.  
  722.         ox = rx;
  723.         oy = 0;
  724.         for (a = 0, i = 0; i < 12*2; ++i) {
  725.             a += D90/12;
  726.             dx = fmul (COS (a), rx);
  727.             dy = fmul (SIN (a), ry);
  728.             gr_move (orgx+ox,        orgy-oy);
  729.             gr_draw (orgx+(dx+ox)/2, orgy-(dy+oy)/2);
  730.             gr_move (orgx-ox,        orgy+oy);
  731.             gr_draw (orgx-(dx+ox)/2, orgy+(dy+oy)/2);
  732.             ox = dx;
  733.             oy = dy;
  734.         }
  735.         dy = sy/2;
  736.     } else {
  737.         orgy += shifty;
  738.         dx = fmul (sx, RSELECT5);
  739.         add_dash (orgx-dx, orgy, orgx-dx, orgy-sy, 16, FONE/2,
  740.                 orgx, orgy, sx, sy);
  741.         add_dash (orgx-dx, orgy, orgx,    orgy,     4, FONE/2,
  742.                 orgx, orgy, sx, sy);
  743.         add_dash (orgx+dx, orgy, orgx+dx, orgy-sy, 16, FONE/2,
  744.                 orgx, orgy, sx, sy);
  745.         add_dash (orgx+dx, orgy, orgx,    orgy,     4, FONE/2,
  746.                 orgx, orgy, sx, sy);
  747.         dy = 0;
  748.     }
  749.     return (dy);
  750. }
  751.  
  752. #undef SEL3D
  753.  
  754. LOCAL_FUNC void NEAR
  755. show_ip (VIEW *view, LVECT IP, OBJECT *pov, int orgx, int orgy, int dx,
  756.     int dy, int maxx, int maxy, int clipx, int clipy, int shifty, int ss,
  757.     int dt)
  758. {
  759.     int    toff;
  760.     VECT    RR;
  761.     int    DD[2];
  762.  
  763.     objects_show (1, view, pov, 0, IP, RR);
  764.     toff = clip_to_screen (DD, RR, maxx, maxy, clipx-dx, clipy-dy, shifty);
  765.     if (!toff) {
  766.         DD[X] = orgx + DD[X];
  767.         DD[Y] = orgy - DD[Y];
  768.         show_diamond (DD[X], DD[Y], dx, dy, ST_HFG, 0);
  769.         keep_inside (DD+X, DD+Y, ss, ss*4, 0, -ss, orgx, orgy, clipx,
  770.             clipy, shifty);
  771.         stroke_frac (DD[X]+ss, DD[Y], dt, 0, 1, ss, ST_HFG);
  772.     }
  773. }
  774.  
  775. LOCAL_FUNC void NEAR
  776. show_bombs (VIEW *view, OBJECT *p, OBJECT *pov, int orgx, int orgy, int sx,
  777.     int sy, int maxx, int maxy, int clipx, int clipy, int shifty, int ss)
  778. {
  779.     int    dx, dy, dt;
  780.     OBJECT    *b;
  781.     LVECT    IP;
  782.  
  783.     dx = fmul (sx, IPDIAMOND);
  784.     dy = fmul (sy, IPDIAMOND);
  785.  
  786.     for (b = CO; b; b = b->next) {
  787.         if (b->owner != CC || ET_BOMB != b->e_type)
  788.             continue;
  789.         dt = (EBM(b)->timpact - st.present) / 100;
  790.         show_ip (view, EBM(b)->IP, pov, orgx, orgy, dx, dy, maxx,
  791.             maxy, clipx, clipy, shifty, ss, dt);
  792.     }
  793.  
  794.     if (!(EX->radar & R_ON)) {
  795.         dt = BombIP (p->R, p->V, 0L, IP)/10;
  796.         show_ip (view, IP, pov, orgx, orgy, dx, dy, maxx, maxy,
  797.             clipx, clipy, shifty, ss, dt);
  798.     }
  799. }
  800.  
  801. LOCAL_FUNC void NEAR
  802. show_target (OBJECT *p, OBJECT *target, VECT RR, int dist, int closure,
  803.     int tti, int orgx, int orgy, int maxx, int maxy, int ss)
  804. {
  805.     int    dd, dx, dy, x, i;
  806.     long    tx, ty, tz;
  807.     int    D[2];
  808.  
  809.     dd = num_size (9L, ss);
  810.     dx = fmul (maxx, FCON(0.25));
  811.     dy = fmul (maxy, FCON(0.25));
  812.     if (!clip_to_screen (D, RR, maxx, maxy, maxx-dx, maxy-dy, 0))
  813. #if 0
  814.         show_bplus (orgx+D[X], orgy-D[Y], dx, dy, FCON(0.125), ST_HFG);
  815. #else
  816.         show_brect (orgx+D[X], orgy-D[Y], dx, dy, FCON(0.75), ST_HFG,
  817.                 0);
  818. #endif
  819.  
  820.     x  = orgx - maxx + 2;
  821.     dy = orgy + maxy - 2 - 3*ss;
  822.     show_data (p, x, dy, 1, EX->hud1 & HUD_KNOTS,
  823.         dist, closure, get_name (p, target, 0), tti, 0, ss, ST_HFG);
  824.  
  825.     tx = (target->R[X] - p->R[X])/VONE;
  826.     ty = (target->R[Y] - p->R[Y])/VONE;
  827.     tz = (target->R[Z] - p->R[Z])/VONE;
  828.     if (labs(tx) > 25000L || labs(ty) > 25000L || labs(tz) > 25000L)
  829.         return;                /* too far out */
  830.  
  831.     x  = orgx + maxx - 5*dd;
  832.     dy = orgy + maxy - 2;
  833.  
  834.     dx = x;
  835.     dx += stroke_str (dx, dy, "P ", ss, ST_HFG);
  836.     i = ihypot2d ((int)tx, (int)ty);
  837.     i = ANG2DEG(ATAN ((int)tz, i));
  838.     dx += stroke_char (dx, dy, (i<0) ? '-' : ' ', ss, ST_HFG);
  839.     stroke_frac (dx, dy, (long)iabs(i), 2, 0, ss, ST_HFG);
  840.  
  841.     dy -= ss;
  842.  
  843.     dx = x;
  844.     dx += stroke_str (dx, dy, "H ", ss, ST_HFG);
  845.     i = ANG2DEG(ATAN ((int)tx, (int)ty));
  846.     if (i < 0)
  847.         i += 360;
  848.     stroke_frac (dx, dy, (long)i, 3, 0, ss, ST_HFG);
  849. }
  850.